package cc.admin.modules.graduate.service.impl;

import cc.admin.common.sys.vo.LoginUser;
import cc.admin.modules.graduate.entity.*;
import cc.admin.modules.graduate.entity.DTO.DesignQuestionsListDto;
import cc.admin.modules.graduate.entity.VO.ExamPaperVo;
import cc.admin.modules.graduate.mapper.*;
import cc.admin.modules.graduate.service.IBlankErrorQuestionsService;
import cc.admin.modules.graduate.service.IChoiceErrorQuestionsService;
import cc.admin.modules.graduate.service.IExamPaperService;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import me.zhyd.oauth.utils.UuidUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Description: 试卷
 * @Author: cc-admin
 * @Date: 2024-12-25
 * @Version: V1.0.0
 */
@Service
public class ExamPaperServiceImpl extends ServiceImpl<ExamPaperMapper, ExamPaper> implements IExamPaperService {

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Autowired
    ExamPaperMapper examPaperMapper;

    @Autowired
    ExamPaperAnswerMapper examPaperAnswerMapper;

    @Autowired
    BlankQuestionsMapper blankQuestionsMapper;

    @Autowired
    ChoiceQuestionsMapper choiceQuestionsMapper;

    @Autowired
    DesignQuestionsListMapper designQuestionsListMapper;

    @Autowired
    DesignQuestionsMapper designQuestionsMapper;

    @Autowired
    DesignAnswerListMapper designAnswerListMapper;

    @Autowired
    DesignAnswerMapper designAnswerMapper;

    @Autowired
    IChoiceErrorQuestionsService choiceErrorQuestionsService;

    @Autowired
    IBlankErrorQuestionsService blankErrorQuestionsService;

    public String linearValue = "1";
    public String queueValue = "2";
    public String stringValue = "3";
    public String treeValue = "4";
    public String graphValue = "5";
    public String searchValue = "6";
    public String sortValue = "7";

    /*
    * 创建卷子
    * */
    @Override
    public HashMap<String, List<ChoiceQuestions>> createExam(ExamPaper examPaper) {
        Map<String, Percent> percentObjectList = examPaper.getPercent();
        Map<String, Percent> designpercentObjectList = examPaper.getDesignPercent();
        Map<String, Percent> breakPercentObjectList = examPaper.getBreakPercent();


        HashMap<String, List<DesignQuestionsListDto>> designQuestionsMap = getDesignQuestionsMap(designpercentObjectList, examPaper);
        // 获取每个科目的选择题
        HashMap<String, List<ChoiceQuestions>> choiceQuestionsMap = getChoiceQuestionsMap(percentObjectList, examPaper);
        // 获取填空题
        HashMap<String, List<BlankQuestions>> breakQuestionsMap = new HashMap<>();
        if (breakPercentObjectList!=null) {
            breakQuestionsMap = getBreakQuestionsMap(breakPercentObjectList, examPaper);
        }
        ExamPaper examPaperToDb = new ExamPaper();
        BeanUtils.copyProperties(examPaper, examPaperToDb);
        ArrayList<String> choiceQuestionIds = new ArrayList<>();
        //根据每个科目的选择题获得id集合
        choiceQuestionsMap.forEach((tab, choiceQuestionsList) -> {
            choiceQuestionsList.forEach(choiceQuestions -> {
                String choiceQuestionsId = choiceQuestions.getId();
                choiceQuestionIds.add(choiceQuestionsId);
            });
        });
        ArrayList<String> designQuestionIds = new ArrayList<>();
        //根据每个科目的选择题获得id集合
        designQuestionsMap.forEach((tab, designQuestionsList) -> {
            designQuestionsList.forEach(designQuestions -> {
                String designQuestionsId = designQuestions.getId();
                designQuestionIds.add(designQuestionsId);
            });
        });

        ArrayList<String> BlankQuestionIds = new ArrayList<>();
        //根据每个科目的选择题获得id集合
        breakQuestionsMap.forEach((tab, blankQuestionsList) -> {
            blankQuestionsList.forEach(blankQuestions -> {
                String blankQuestionsId = blankQuestions.getId();
                BlankQuestionIds.add(blankQuestionsId);
            });
        });
        String choiceQuestionIdsString = String.join(",", choiceQuestionIds);
        String designQuestionIdsString = String.join(",", designQuestionIds);
        if (BlankQuestionIds!=null) {
            String blankQuestionIdsString = String.join(",", BlankQuestionIds);
            examPaperToDb.setBlankIds(blankQuestionIdsString);
        }
//        String percentsString = String.join(",", examPaper.getPercent().get());
        examPaperToDb.setChoiceIds(choiceQuestionIdsString);
        examPaperToDb.setDesignIds(designQuestionIdsString);
//        examPaperToDb.setPercentText(percentsString);
        examPaperMapper.insert(examPaperToDb);

        return choiceQuestionsMap;


    }

    @Override
    public void updateExam(ExamPaper examPaper) {


    }

    @Override
    public ExamPaperVo getexampaper(String id) {
        System.out.println(id);
        String id1 = JSONObject.parseObject(id).getString("id");
        LambdaQueryWrapper<ExamPaper> examPaperLambdaQueryWrapper = new LambdaQueryWrapper<>();
        examPaperLambdaQueryWrapper.eq(id != null, ExamPaper::getId, id1);
        ExamPaper examPaper = examPaperMapper.selectOne(examPaperLambdaQueryWrapper);
        String[] designQuestionIds = null;
        if (examPaper.getDesignIds()!=null) {
            designQuestionIds = examPaper.getDesignIds().split(",");
        }
        String[] choiceQuestionIds = null;
        if (examPaper.getChoiceIds()!=null) {
            choiceQuestionIds = examPaper.getChoiceIds().split(",");
        }
        String[] blankQuestionIds = new String[0];
        if (examPaper.getBlankIds()!=null&&examPaper.getBlankIds()!="") {
            blankQuestionIds = examPaper.getBlankIds().split(",");
        }
        ExamPaperVo examPaperVo =  new ExamPaperVo();
        BeanUtils.copyProperties(examPaper,examPaperVo);
        examPaperVo.setChoiceIds(examPaper.getChoiceIds());
        if (designQuestionIds.length != 0) {
            List<String> designQuestionIdsList = Arrays.stream(designQuestionIds).collect(Collectors.toList());
            List<DesignQuestionsListDto> DesignQuestionsList = designQuestionsListMapper.selectBatchIds(designQuestionIdsList);

            DesignQuestionsList.forEach(designQuestionsListDto -> {
                //放应用题的子数据
                String childIds = designQuestionsListDto.getChildIds();
                List<String> childIdsList = Arrays.stream(childIds.split(",")).collect(Collectors.toList());
                List<DesignQuestions> designQuestions = designQuestionsMapper.selectBatchIds(childIdsList);
                designQuestionsListDto.setQuestionList(designQuestions);
            });

            examPaperVo.setDesignQuestionsListDtoList(DesignQuestionsList);
        }
        if (choiceQuestionIds.length != 0) {
            List<String> choiceQuestionIdsList = Arrays.stream(choiceQuestionIds).collect(Collectors.toList());
            List<ChoiceQuestions> choiceQuestionsList = choiceQuestionsMapper.selectBatchIds(choiceQuestionIdsList);
            examPaperVo.setChoiceQuestionsList(choiceQuestionsList);
        }

        if (blankQuestionIds.length != 0) {
            List<String> blankQuestionIdsList = Arrays.stream(blankQuestionIds).collect(Collectors.toList());
            List<BlankQuestions> blankQuestionsList = blankQuestionsMapper.selectBatchIds(blankQuestionIdsList);
            examPaperVo.setBlankQuestionsList(blankQuestionsList);
        }
        return examPaperVo;
    }

    /*
    * 保存试卷作答
    * */
    @Override
    @Transactional
    public void saveExamAnswer(ExamPaperAnswer examPaperAnswer) {
        String id = examPaperAnswer.getId();
        ExamPaper examPaper = new ExamPaper();
        LambdaUpdateWrapper<ExamPaper> examPaperLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        examPaperLambdaUpdateWrapper.eq(ExamPaper::getId,id);
        examPaperLambdaUpdateWrapper.set(ExamPaper::getType,"已完成");
        examPaperMapper.update(examPaper,examPaperLambdaUpdateWrapper);


        List<String> choiceAnswer = examPaperAnswer.getChoiceAnswer();
        List<ChoiceQuestions> choiceQuestionsList = examPaperAnswer.getChoiceQuestionsList();
        //存入选择题错题
        for (int i = 0; i < choiceQuestionsList.size(); i++) {
            if (!choiceQuestionsList.get(i).getAnswer().equals(choiceAnswer.get(i))){
                ChoiceErrorQuestions choiceErrorQuestions = new ChoiceErrorQuestions();
                ChoiceQuestions choiceQuestions = choiceQuestionsList.get(i);
                BeanUtils.copyProperties(choiceQuestions,choiceErrorQuestions);
                choiceErrorQuestions.setRealAnswer(choiceErrorQuestions.getAnswer());
                choiceErrorQuestions.setAnswer(choiceAnswer.get(i));
                LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
                choiceErrorQuestions.setUserId(user.getUsername());
                choiceErrorQuestions.setQuestionId(choiceErrorQuestions.getId());
                String choiceErrId = UuidUtils.getUUID();
                choiceErrorQuestions.setId(choiceErrId);
                choiceErrorQuestionsService.save(choiceErrorQuestions);
            }
        }
        List<String> blankAnswer = examPaperAnswer.getBlankAnswer();
        ArrayList<String> designAnserIdList = new ArrayList<>();

        String choiceAnswerString = StringUtils.join(choiceAnswer, ",");
        String blankAnswerString = StringUtils.join(blankAnswer, ",");

        examPaperAnswer.setChoiceAnswerString(choiceAnswerString);
        examPaperAnswer.setBlankAnswerString(blankAnswerString);

        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        List<DesignAnswerList> designAnswerList = examPaperAnswer.getDesignAnswer();
        designAnswerList.forEach(designQuestionsListDto -> {
            String parentId = UuidUtils.getUUID();

            //将应用题的所有小题保存进做题表中
            designQuestionsListDto.getQuestionList().forEach(designQuestions -> {
                DesignAnswer designAnswer = new DesignAnswer();
                BeanUtils.copyProperties(designQuestions,designAnswer);
                designAnswer.setUserId(user.getId());
                designAnswer.setUserName(user.getRealname());
                String uuid = UuidUtils.getUUID();
                designAnswer.setQuestionId(designAnswer.getId());
                designAnswer.setParentId(parentId);
                designAnswer.setId(uuid);
                designAnswerMapper.insert(designAnswer);
            });
            DesignAnswerList designAnswerList1 = new DesignAnswerList();
            BeanUtils.copyProperties(designQuestionsListDto,designAnswerList1);
            designAnswerList1.setUserName(user.getRealname());
            designAnswerList1.setQuestionId(designAnswerList1.getId());
            designAnswerList1.setId(parentId);
            designAnserIdList.add(parentId);
            //将应用题的所有大题保存到主表中
            designAnswerListMapper.insert(designAnswerList1);


        });
        String designAnserIdListString = StringUtils.join(designAnserIdList, ",");
        examPaperAnswer.setDesignAnswerIds(designAnserIdListString);
        String uuid = UuidUtils.getUUID();
        examPaperAnswer.setExamPaperId(examPaperAnswer.getId());
        examPaperAnswer.setId(uuid);
        examPaperAnswerMapper.insert(examPaperAnswer);
    }

    /*
     * percent 要分配的集合
     *
     * numberToAllocate   被分配的整数
     *
     * */
    public int[] allocatePercent(List<String> percent, Integer numberToAllocate) {


        double totalPercent = 0;
        double[] percentValues = new double[percent.size()];

        // 计算非空比例的总和
        for (int i = 0; i < percent.size(); i++) {
            String strPercent = percent.get(i);
            if (!strPercent.isEmpty()) {
                try {
                    percentValues[i] = Double.parseDouble(strPercent);
                    totalPercent += percentValues[i];
                } catch (NumberFormatException e) {
                    System.out.println("Invalid percentage at index " + i);
                }
            }
        }

        if (totalPercent == 0) {
            System.out.println("No valid percentages provided, cannot allocate.");
            return null;
        }

        int[] allocatedNumbers = new int[percent.size()];
        int remaining = numberToAllocate; // 记录剩余未分配的数量

        // 按比例分配整数（先按照比例分配）
        for (int i = 0; i < percent.size(); i++) {
            if (!percent.get(i).isEmpty()) {
                double proportion = percentValues[i] / totalPercent;
                int allocated = (int) (proportion * numberToAllocate);
                allocatedNumbers[i] = allocated;
                remaining -= allocated;
            } else {
                allocatedNumbers[i] = 0;
            }
        }

        // 将剩余数量分配给非空比例项（从第一个非空比例项开始循环分配）
        int index = 0;
        while (remaining > 0) {
            if (!percent.get(index).isEmpty()) {
                allocatedNumbers[index]++;
                remaining--;
            }
            index = (index + 1) % percent.size();
        }

        for (int i = 0; i < percent.size(); i++) {
            System.out.println("Allocated number for index " + i + ": " + allocatedNumbers[i]);
        }
        return allocatedNumbers;
    }

    public HashMap<String, List<DesignQuestionsListDto>> getDesignQuestionsMap(Map<String, Percent> percentObjectMap, ExamPaper examPaper) {
        HashMap<String, List<DesignQuestionsListDto>> allQuestionMap = new HashMap<>();
        String needError = examPaper.getNeedError();
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();

        ArrayList<String> questionIds = new ArrayList<>();
        Set<String> tabSet = new HashSet<String>();
//        for (int i = 0; i < percentObjectList.size(); i++) {
//
//        }
        final int[] i = {0};
        percentObjectMap.forEach((tab, percent) -> {
            //该科目所有应用题的集合
            List<DesignQuestionsListDto> allQuestionList = new ArrayList<>();
            List<String> percentArr1 = percent.getPercentArr();
            tabSet.add(tab);
            //每科题目总数
            Integer quastionQuantity = examPaper.getDesignQuantity().get(i[0]);
            //
            int[] percentArr = allocatePercent(percentArr1, quastionQuantity);
            //便利每个科目集合
            if (percentArr!=null) {
                for (int j = 0; j < percentArr.length; j++) {
                    //每个题目所占的题数
                    Integer ItemPercent = percentArr[j];
                    List<DesignQuestionsListDto> DesignQuestionsList = null;
                    if (needError ==null || needError.equals("2")) {
                        DesignQuestionsList = designQuestionsListMapper.questionsList(String.valueOf(j + 1), ItemPercent, tab);
                    }else {
                        // 查询当前用户错误选择题的id
                        ArrayList<String> errorIds = new ArrayList<>();
                        LambdaQueryWrapper<DesignAnswerList> errorQueryWrapper1 = new LambdaQueryWrapper<>();
                        errorQueryWrapper1.eq(DesignAnswerList::getUserId, user.getUsername());
                        errorQueryWrapper1.groupBy(DesignAnswerList::getQuestionId);
                        errorQueryWrapper1.select(DesignAnswerList::getQuestionId);
                        List<Map<String, Object>> maps = designAnswerListMapper.selectMaps(errorQueryWrapper1);
                        maps.forEach(errorQuestions -> {
                            if (errorQuestions!=null) {
                                errorIds.add(errorQuestions.get("question_id").toString());
                            }
                        });
                        // 查询选择题
                        LambdaQueryWrapper<DesignQuestionsListDto> queryWrapper = new LambdaQueryWrapper<>();
                        // 查询题目类型
                        if (String.valueOf(j + 1) != null && !String.valueOf(j + 1).isEmpty()) {
                            queryWrapper.like(DesignQuestionsListDto::getCategoryIds, String.valueOf(j + 1));
                        }

                        // 按 tab 筛选
                        if (tab != null && !tab.isEmpty()) {
                            queryWrapper.eq(DesignQuestionsListDto::getMajorId, tab);
                        }
                        if (errorIds.size() > 0) {
                            queryWrapper.in(DesignQuestionsListDto::getId, errorIds);
                        }
                        // 查询数据条数
                        if (ItemPercent != null) {
                            queryWrapper.last("ORDER BY RAND() LIMIT " + ItemPercent);
                        }
                        DesignQuestionsList = designQuestionsListMapper.selectList(queryWrapper);
                    }
                    allQuestionList.addAll(DesignQuestionsList);
                    allQuestionList.forEach(designQuestions -> {
                        questionIds.add(designQuestions.getId());
                    });
                }
            }
            allQuestionMap.put(tab, allQuestionList);
            i[0]++;
        });
        return allQuestionMap;
    }

    public HashMap<String, List<ChoiceQuestions>> getChoiceQuestionsMap(Map<String, Percent> percentObjectMap, ExamPaper examPaper) {
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        HashMap<String, List<ChoiceQuestions>> allQuestionMap = new HashMap<>();
        String needError = examPaper.getNeedError();
        ArrayList<String> questionIds = new ArrayList<>();
        Set<String> tabSet = new HashSet<String>();
//        for (int i = 0; i < percentObjectList.size(); i++) {
//
//        }
        final int[] i = {0};
        percentObjectMap.forEach((tab, percent) -> {
            //该科目所有选择题的集合
            List<ChoiceQuestions> allQuestionList = new ArrayList<>();
            List<String> percentArr1 = percent.getPercentArr();
            tabSet.add(tab);
            //每科题目总数
            Integer quastionQuantity = examPaper.getQuantity().get(i[0]);
            int[] percentArr = allocatePercent(percentArr1, quastionQuantity);
            //便利每个科目集合
            if (percentArr!=null) {
                for (int j = 0; j < percentArr.length; j++) {
                    //每个题目所占的题数
                    Integer ItemPercent = percentArr[j];
                    List<ChoiceQuestions> ChoiceQuestionsList = null;
                    if (needError ==null || needError.equals("2")) {
                        ChoiceQuestionsList = choiceQuestionsMapper.questionsList(String.valueOf(j + 1), ItemPercent, tab);
                    }else {
                        // 查询当前用户错误选择题的id
                        ArrayList<String> errorIds = new ArrayList<>();
                        LambdaQueryWrapper<ChoiceErrorQuestions> errorQueryWrapper1 = new LambdaQueryWrapper<>();
                        errorQueryWrapper1.eq(ChoiceErrorQuestions::getUserId, user.getUsername());
                        errorQueryWrapper1.groupBy(ChoiceErrorQuestions::getQuestionId);
                        errorQueryWrapper1.select(ChoiceErrorQuestions::getQuestionId);
                        List<Map<String, Object>> maps = choiceErrorQuestionsService.listMaps(errorQueryWrapper1);
                        maps.forEach(errorQuestions -> {
                            if (errorQuestions!=null) {
                                errorIds.add(errorQuestions.get("question_id").toString());
                            }
                        });
                        // 查询选择题
                        LambdaQueryWrapper<ChoiceQuestions> queryWrapper = new LambdaQueryWrapper<>();
                        // 查询题目类型
                        if (String.valueOf(j + 1) != null && !String.valueOf(j + 1).isEmpty()) {
                            queryWrapper.like(ChoiceQuestions::getCategoryIds, String.valueOf(j + 1));
                        }

                        // 按 tab 筛选
                        if (tab != null && !tab.isEmpty()) {
                            queryWrapper.eq(ChoiceQuestions::getMajorId, tab);
                        }
                        if (errorIds.size() > 0) {
                            queryWrapper.in(ChoiceQuestions::getId, errorIds);
                        }
                        // 查询数据条数
                        if (ItemPercent != null) {
                            queryWrapper.last("ORDER BY RAND() LIMIT " + ItemPercent);
                        }
                        ChoiceQuestionsList = choiceQuestionsMapper.selectList(queryWrapper);
                    }
                    allQuestionList.addAll(ChoiceQuestionsList);
                    allQuestionList.forEach(ChoiceQuestions -> {
                        questionIds.add(ChoiceQuestions.getId());
                    });
                }
            }
            allQuestionMap.put(tab, allQuestionList);
            i[0]++;
        });
        return allQuestionMap;
    }

    public HashMap<String, List<BlankQuestions>> getBreakQuestionsMap(Map<String, Percent> percentObjectMap, ExamPaper examPaper) {
        HashMap<String, List<BlankQuestions>> allQuestionMap = new HashMap<>();
        LoginUser user = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String needError = examPaper.getNeedError();
        ArrayList<String> questionIds = new ArrayList<>();
        Set<String> tabSet = new HashSet<String>();
//        for (int i = 0; i < percentObjectList.size(); i++) {
//
//        }
        final int[] i = {0};
        percentObjectMap.forEach((tab, percent) -> {
            //该科目所有选择题的集合
            List<BlankQuestions> allQuestionList = new ArrayList<>();
            List<String> percentArr1 = percent.getPercentArr();
            tabSet.add(tab);
            //每科题目总数
            Integer quastionQuantity = examPaper.getBlankQuantity().get(i[0]);
            int[] percentArr = allocatePercent(percentArr1, quastionQuantity);
            //便利每个科目集合
            if (percentArr!=null) {
                for (int j = 0; j < percentArr.length; j++) {
                    //每个题目所占的题数
                    Integer ItemPercent = percentArr[j];
                    List<BlankQuestions> blankQuestionsList = null;
                    if (needError ==null || needError.equals("2")) {
                        blankQuestionsList = blankQuestionsMapper.questionsList(String.valueOf(j + 1), ItemPercent, tab);
                    }else {
                        // 查询当前用户错误选择题的id
                        ArrayList<String> errorIds = new ArrayList<>();
                        LambdaQueryWrapper<BlankErrorQuestions> errorQueryWrapper1 = new LambdaQueryWrapper<>();
                        errorQueryWrapper1.eq(BlankErrorQuestions::getUserId, user.getUsername());
                        errorQueryWrapper1.groupBy(BlankErrorQuestions::getQuestionId);
                        errorQueryWrapper1.select(BlankErrorQuestions::getQuestionId);
                        List<Map<String, Object>> maps = blankErrorQuestionsService.listMaps(errorQueryWrapper1);
                        maps.forEach(errorQuestions -> {
                            if (errorQuestions!=null) {
                                errorIds.add(errorQuestions.get("question_id").toString());
                            }
                        });
                        // 查询选择题
                        LambdaQueryWrapper<BlankQuestions> queryWrapper = new LambdaQueryWrapper<>();
                        // 查询题目类型
                        if (String.valueOf(j + 1) != null && !String.valueOf(j + 1).isEmpty()) {
                            queryWrapper.like(BlankQuestions::getCategoryIds, String.valueOf(j + 1));
                        }

                        // 按 tab 筛选
                        if (tab != null && !tab.isEmpty()) {
                            queryWrapper.eq(BlankQuestions::getMajorId, tab);
                        }
                        if (errorIds.size() > 0) {
                            queryWrapper.in(BlankQuestions::getId, errorIds);
                        }
                        // 查询数据条数
                        if (ItemPercent != null) {
                            queryWrapper.last("ORDER BY RAND() LIMIT " + ItemPercent);
                        }
                        blankQuestionsList = blankQuestionsMapper.selectList(queryWrapper);
                    }
                    allQuestionList.addAll(blankQuestionsList);
                    allQuestionList.forEach(blankuestions -> {
                        questionIds.add(blankuestions.getId());
                    });
                }
            }
            allQuestionMap.put(tab, allQuestionList);
            i[0]++;
        });
        return allQuestionMap;
    }

}


